/** @author A0105514U */
// @author A0105514U
package storage;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import global.Task;

import org.junit.Before;
import org.junit.Test;

// White box testing
public class StorageTestDriver {
	Task task1,task2;
	String path,userName;
	String modRecordFolder;
	
	@Before
	public void init(){
		userName = System.getProperty("user.name");
		path = "C:\\Users\\"+userName+"\\Documents\\BeautyRoxy Storage";
		modRecordFolder = "C:\\Users\\"+userName+"\\Documents\\BeautyRoxy Storage\\Modification Record";
		task1 = new Task("time#MA3269 Test#Lecture Theather 15#201302281608#201303311200");
		task2 = new Task("time#MA3269 Test 2#Lecture Theather 16#201302281608#201303311200");
		
		Storage.init();
		cleanUpForTesting();
	}
	
	private void cleanUpForTesting(){
		
		ArrayList<String> fileNameList = Storage.getFileNameList();
		for(int i=0;i<fileNameList.size();i++){
			String fileName = fileNameList.get(i);
			Storage.deleteFileWithoutRecord(fileName);
		}
		
		fileNameList = Storage.getDoneFileNameList();
		for(int i=0;i<fileNameList.size();i++){
			String fileName = fileNameList.get(i);
			Storage.deleteFileWithoutRecord(fileName);
		}
		
		File file = new File(path+"\\Modification Record\\Command Storage.txt");
		if(file.exists()){
			file.delete();
		}
		
		try{
			file.createNewFile();
		}catch(Exception e){
			
		}
	}
	
	// Test that the init() function of Storage really set up the Storage
	@Test
	public void testInit(){

		File file = new File(path);
		assertTrue(file.exists());
		File modRecord = new File(modRecordFolder);
		assertTrue(modRecord.exists());
		assertTrue(modRecord.isDirectory());
	}
	
	// Test that normal tasks can be successfully added.
	@Test
	public void test1(){
		try {
			ArrayList<String> expectedFileName = new ArrayList<String>();

			String taskFileName1 = task1.getTaskFileName();
			Storage.addFileWithoutRecord(task1);
			
			String taskFileName2 = task2.getTaskFileName();
			Storage.addFileWithoutRecord(task2);
			
			expectedFileName.add(taskFileName2);
			expectedFileName.add(taskFileName1);
			
			ArrayList<String> actualFileNameList = Storage.getFileNameList();
			
			assertEquals(expectedFileName,actualFileNameList);
			
			Storage.deleteFileWithoutRecord(taskFileName1);
			assertTrue(Storage.getFileNameList().size() == 1);
			assertTrue(Storage.isRecordEmpty());
			Storage.deleteFile(taskFileName2);
			
			// This is expected to be true because the task has not been sync yet and hence
			// no record will be added to the storage.
			assertTrue(Storage.isRecordEmpty());
			assertTrue(Storage.getFileNameList().size() == 0);
		} catch (IOException e) {
			assertTrue(false);
		}
	}
	
	// Test that null tasks are handled properly
	@Test
	public void test2(){
		try {
			Task task1 = null;
			
			ArrayList<String> expectedFileName = new ArrayList<String>();
			Storage.addFileWithoutRecord(task1);
			assertTrue(true);
		} catch (IOException e) {
			assertTrue(false);
		}
	}
	
	// Test addFileWithoutRecord and deleteFileWithoutRecord
	@Test
	public void test3(){
		try {
			Storage.addFileWithoutRecord(task1);
			File file = new File(path+"\\"+task1.getTaskFileName());
			assertTrue(file.exists());
			Storage.deleteFileWithoutRecord(task1.getTaskFileName());
			assertFalse(file.exists());
		} catch (IOException e) {
			assertFalse(true);
			e.printStackTrace();
		}
	}
	
	// Testing tasks with special characters in task names
	@Test
	public void test4(){
		String taskName = "he\"ll^o";
		String filteredTaskName = "hello";
		Task task = new Task("float#"+taskName+"##null#null");
		try {
			Storage.addFileWithoutRecord(task);
			Task newTask = Storage.getFileContentAsTask(task.getTaskFileName());
			assertEquals(newTask.getTaskName(),filteredTaskName);
			Storage.deleteFileWithoutRecord(task.getTaskFileName());
		} catch (IOException e) {
			assertTrue(false);
			e.printStackTrace();
		}
	}
	
	// Test getFileContentAsTask()
	@Test
	public void test5(){
		try{
			task1.setSync();
			Storage.addFile(task1);
			String fileName = task1.getTaskFileName();
			Task AltTask1 = Storage.getFileContentAsTask(fileName);
			assertEquals(task1.getTaskName(),AltTask1.getTaskName());
			assertEquals(task1.getFormattedTaskString(),AltTask1.getFormattedTaskString());
			assertEquals(task1.getStartTime(),AltTask1.getStartTime());
			assertEquals(task1.getSyncStatus(),AltTask1.getSyncStatus());
			Storage.deleteFileWithoutRecord(fileName);
		}catch(IOException e){
			assertTrue(false);
			e.printStackTrace();
		}
	}
	
	// Test isFileSync()
	@Test
	public void test6(){
		try {
			task1.setSync();
			Storage.addFileWithoutRecord(task1);
			assertTrue(Storage.isFileSync(task1.getTaskFileName()));
			Storage.deleteFileWithoutRecord(task1.getTaskFileName());
		} catch (IOException e) {
			assertTrue(false);
			e.printStackTrace();
		}
	}
	
	// Test isRecordExist()
	@Test
	public void test7(){
		try{
			Storage.addFile(task1);
			assertFalse(Storage.isRecordEmpty());
			assertTrue(Storage.isRecordExist("add", task1.getTaskFileName()));
			Storage.getRecord();
			Storage.deleteFile(task1.getTaskFileName());
			assertTrue(Storage.isRecordEmpty());
			assertFalse(Storage.isRecordExist("add", task1.getTaskFileName()));
		} catch (IOException e) {
			assertTrue(false);
			e.printStackTrace();
		}
	}
}
